package com.fitso.model.service.user;

import java.util.List;

import javax.annotation.Resource;

import org.jasypt.util.password.PasswordEncryptor;
import org.springframework.stereotype.Service;

import com.fitso.model.bean.User;
import com.fitso.model.util.common.StringUtils;

/**
 * Secure implementation of {@link UserService} that wraps another
 * {@link UserService} but provides password digest on save and credential
 * checking on fetch
 * 
 * @author timothystorm
 */
@Service(value = "SecureUserService")
public class SecureUserService implements UserService {

	@Resource(name = "SimpleUserService")
	private UserService _userService;

	@Resource(name = "StrongPasswordEncryptor")
	private PasswordEncryptor _encryptor;

	/**
	 * Encrypts the user password before calling the underlying
	 * {@link UserService#save(User)}
	 */
	public void save(User user) {
		user.setPassword(_encryptor.encryptPassword(user.getPassword()));
		_userService.save(user);
	}

	/**
	 * Encrypts the user password before calling the underlying
	 * {@link UserService#edit(User)}. Only re-encrypt if the password is
	 * different from what is currently persisted.
	 */
	public void edit(User user) {
		User persistedUser = fetch(user.getId());
		if (!StringUtils.equals(user.getPassword(), persistedUser.getPassword())) {
			user.setPassword(_encryptor.encryptPassword(user.getPassword()));
		}
		_userService.edit(user);
	}

	public void delete(User user) {
		_userService.delete(user);
	}

	public User fetch(Long id) {
		return _userService.fetch(id);
	}

	/**
	 * Validates the {@link User} password credentials
	 * 
	 * @throws UserCredentailsException
	 *             if the password isn't
	 */
	public User fetch(String email, String password) {
		User user = _userService.fetch(email, password);

		if (user == null || !_encryptor.checkPassword(password, user.getPassword())) {
			return null;
		}
		return user;
	}

	public List<User> fetch() {
		return _userService.fetch();
	}
}
